home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-09 | 12.8 KB | 330 lines | [TEXT/MPS ] |
- ;
- ; M O - T h e M o m e n t u m C D E V
- ;
- ; INIT to patch DragGrayRgn to allow ‘tossing’ of windows
- ; © 1991, 1992 Exodus Software
- ; Programmed by Jim Stegman & Bill Johnson.
- ; Idea by David Griggs, Apple System Engineer @ Cincinnati Office
-
- ; The idea is to allow a user to drag a window, then release the mouse button
- ; while still dragging, to ‘toss’ it across the screen.
-
- ; DragGrayRgn is called whenever a programmer wants the user to see feedback of
- ; a dragging operation, by dragging around a gray outline of the item. DragGrayRgn
- ; maintains control until the mouse button is released.
-
- ; We need to alter it’s functionality in two ways: we need control once the user has
- ; released the mouse, so we can calculate the velocity and direction to ‘toss’ the region,
- ; and then to actually move it across the screen along its trajectory. But in order to
- ; be able to calculate the velocity and direction, we need to know where the region
- ; was before the user released the button, as well as after. Once the region comes
- ; to a “rest”, where it’s velocity is zero, we return control to the caller.
-
- ; DragGrayRgn has an ActionProc parameter, which is a routine supplied by the
- ; programmer, that will be called repeatedly while the user is dragging. This INIT
- ; patches DragGrayRgn so that our ActionProc is installed. This is used here to
- ; write the latest mouseLoc and TickCount into our data area. Care is taken if there
- ; is already an ActionProc, so that it gets passed execution after our ActionProc.
-
- ; The original DragGrayRgn is called by JSR so that we get execution back when it is
- ; done, so that we can ‘toss’ the region.
-
- ; This INIT has a number of variables which are adjustable by the CDEV. They
- ; are as follows:
-
- ; Force of Gravity: an integer from 0 to 100 that will pull the region
- ; in a given direction. Zero is NO gravity, 100 is max.
- ; Direction of Gravity: a point that defines the ‘head’ of an arrow, where
- ; the tail is at (0, 0). Thus, (1, 0) for a direction is
- ; equivalent to a gravity pull of straight down.
- ; DeskTop Friction: an integer from 1 to 100 that represents at what rate
- ; the region will slow down. One is very low friction,
- ; and a value of 100 will make it operate normally-no toss
- ; Bounce Friction: an integer from 1 to 100 that represents how much ‘energy’
- ; is lost each time the region ‘bounces’ off one of the sides
- ; of the screen. A value of 100 will make the region ‘stick’
- ; to the side, unless a high force of gravity pulls it down.
-
- ; All parameters that are listed from 0 or 1 to 100 are constrained to that
- ; range. In other words, 100 is used if a value of 23,719 is entered.
-
- IMPORT InstallGestaltPtrReference
- IMPORT TossGrayRgn
- IMPORT IsMoEnabled
- IMPORT ShowINIT ; include the routine that displays the icon at boot time
-
-
- PRINT OFF
- INCLUDE 'QuickEqu.a'
- INCLUDE 'ScriptEqu.a'
- INCLUDE 'ToolEqu.a'
- INCLUDE 'SysEqu.a'
- INCLUDE 'Traps.a'
- INCLUDE 'PackMacs.a'
- PRINT ON
-
-
- lagTime equ 2 ; min. num of ticks inbetween time/mouseLoc samplings
- patchProcPtr equ -4 ; our local VAR for Install routine
- DragTrap equ $105 ; trap number for DragGrayRgn ($A905)
- PatchSize equ 6000 ; number of bytes allocated for the patches in RAM - can't do it
- ; by subtracting addresses because we need to include linked-in
- ; Pascal.
- RsrcSize equ 14
- IconID EQU -4064 ; the resource id of our ICN#
-
-
- STARTPLACE FUNC EXPORT
-
- ; here is the entry, where we are called at boot time
-
- MOVE.W #IconID, -(SP) ; push the icon id
- MOVE.W #-1, -(SP) ; default parameter
- BSR ShowINIT ; draw the icon
-
- CLR.W -(SP) ; make room for a result
- _Button ; is the mouse button down?
- MOVE.W (SP)+, D0 ; herein lies the answer
- BNE.S WeBeeDone ; if so, do not install me
-
- BRA.S Install ; patch as patch can!
- WeBeeDone
- RTS
-
- ;******** I N S T A L L I N I T ************
- ; The Install routine below puts all the code and data between the labels,
- ; START & FINISH, into the System Heap.
-
- Install
- ; _debugger
- ; get and save the addresses of the original routines
- MOVE.W #DragTrap, D0 ; GetTrapAddress expects the trap num in D0
- _GetTrapAddress ; … and returns the trap address in A0
- LEA oldDragTrap, A1
- MOVE.L A0, (A1) ; save the old trap address
-
- ; allocate memory in the System Heap for our code
-
- MOVE.L #PatchSize, D0 ; NewPtr expects the SIZE to be in D0
- _NewPtr SYS ; … and returns the new pointer in A0
- TST D0 ; check the result code
- BNE.S WeBeeDone ; if it’s an error, DO NOT install!
-
- LINK A6, #-4 ; we have 1 local: patchProcPtr
- MOVE.L A0, patchProcPtr(A6) ; save the address of our new ptr
-
- CLR.L -(SP) ; make room for the resource handle
- MOVE.L #$4D4F6474, -(SP) ; type 'MOdt'
- MOVE.W #$F038, -(SP) ; with ID# -4040
- _GetResource
- MOVE.L (SP)+, D0 ; get the resource handle
- BEQ.S NoResource ; if nil, use our defaults that exist in the DC statements
- MOVEA.L D0, A0
- MOVEA.L (A0), A0 ; dereference it to get the source address
- LEA TossParam, A1 ; get the destination
- MOVE.L #RsrcSize, D0
- _BlockMove ; copy it into this code
-
- NoResource
- MOVEA.L patchProcPtr(A6), A1 ; get ready for our BlockMove
- LEA Start, A0 ; set up the source address
- MOVE.L #PatchSize, D0 ; BlockMove expects the SIZE to be in D0
- _BlockMove ; install our code & data in the System Heap
-
- ; the following allows the CDEV to change our parameters
- LEA TossParam, A0
- LEA Start, A1
- SUBA.L A1, A0 ; determine the offset
- MOVE.L A0, D0
- MOVEA.L patchProcPtr(A6), A1 ; get our ptr in the system heap
- ADDA.L D0, A1 ; make it point to the TossParam data structure
- MOVE.L A1, -(SP) ; push the ptr
- JSR InstallGestaltPtrReference ; install it so the CDEV can reference it
-
- ; patch the DragGrayRgn trap
-
- MOVE.W #DragTrap, D0 ; SetTrapAddress expects the trap num in D0
- MOVE.L patchProcPtr(A6), A0 ; also the address of the new routine in A0
- _SetTrapAddress ; the new routine is installed
-
-
- UNLK A6
- RTS ; installation is complete!
-
- ; next is the stuff that will get called whenever the trap DragGrayRgn is
- ; invoked. First, we install our ActionProc, then call DragGrayRgn. When
- ; DragGrayRgn returns, we will commence tossing.
- ;
- ; State of the Stack when called: ( after I execute my LINK A6 instruction )
- ;
- ; DESC SIZE OFFSET(A6) PASCAL TYPE
- ; result space 4 30 longInt
- ; theRgn 4 26 RgnHandle
- ; startPt 4 22 point
- ; limitRect 4 18 Rect (RectPtr since Rect > 4 bytes)
- ; slopRect 4 14 Rect (RectPtr since Rect > 4 bytes)
- ; axis 2 10 integer
- ; ActionProc 4 8 ProcPtr
- ; return address 4 4 pointer
- ; A6 4 0
-
- Start
- ;******** D R A G G R A Y R G N P A T C H ************
-
- CLR.W -(SP) ; clear room on the stack for the boolean result
- PEA TossParam ; the address of the TossParam Block
- JSR IsMoEnabled
- MOVE.W (SP)+, D0 ; get the result
- BNE.S MoIsGo
- ; Mo is not enabled, just call the original DragGrayRgn
- LEA oldDragTrap, A0 ; get the original address of the call
- MOVEA.L (A0), A0 ; dereference to get the trap address
- JMP (A0) ; execute it
-
- MoIsGo
- LINK A6, #0 ; no locals req’d, but a stack frame helps
- LEA oldMouseLoc, A0
- MOVE.L 22(A6), (A0) ; init our mouse location to the startPoint
- LEA oldTime, A0
- MOVE.L Ticks, (A0) ; init to the current time
- LEA oldActionProc, A0
- MOVE.L 8(A6), (A0) ; get the passed in ActionProc, & save it
-
- ; now get ready to call DragGrayRgn
- CLR.L -(SP) ; make room for our result
- MOVE.L 26(A6), -(SP) ; push the theRgn parmeter
- MOVE.L 22(A6), -(SP) ; push the startPt
- MOVE.L 18(A6), -(SP) ; push the address of the limitRect
- MOVE.L 14(A6), -(SP) ; push the address of the slopRect
- MOVE.W 10(A6), -(SP) ; push the axis parameter
- PEA myActionProc ; push the address of my Action proc
- LEA oldDragTrap, A0 ; get the original address of the call
- MOVEA.L (A0), A0 ; dereference to get the trap address
- JSR (A0) ; execute it
-
- ; execution comes back here when the mouse is released
- MOVE.L (SP)+, D2 ; get the result
- CMP.W #$8000, D2 ; was it out of the slop Rect?
- BEQ.S QuitDrag ; yes, don’t toss it
-
- ; JSR UpdateOldLocAndTime ; get the latest & greatest mouseLoc & time
- CLR.L -(SP) ; make room for our result
- MOVE.L 26(A6), -(SP) ; push the theRgn parmeter
- MOVE.L D2, -(SP) ; push the result from DragGrayRgn
- MOVE.L 22(A6), -(SP) ; push the startPt
- MOVE.L 18(A6), -(SP) ; push the address of the limitRect
- MOVE.L 14(A6), -(SP) ; push the address of the slopRect
- MOVE.W 10(A6), -(SP) ; push the axis parameter
- PEA ScratchParam ; the address of the ScratchParam Block
- PEA TossParam ; the address of the TossParam Block
- JSR TossGrayRgn ; toss the window until it stops
- MOVE.L (SP)+, D2 ; get the result
- QuitDrag
- UNLK A6 ; dump our local stack frame
- MOVEA.L (SP)+, A0 ; get our caller
- ADDA.L #22, SP ; dump the parameters
- MOVE.L D2, (SP) ; set the result
- JMP (A0) ; return to whomever called me…
-
-
- ;******** A C T I O N P R O C ************
- myActionProc
- JSR SetLocAndTime
- LEA oldActionProc, A0 ; get the original proc
- MOVEA.L (A0), A0
- MOVE.L A0, D0 ; move it to a data register so we can check its validity
- BLE.S nilActionProc ; is it nil?
- JMP (A0) ; no, jump to it
- nilActionProc
- RTS ; yes, it’s nil, just return
-
- ;******** S U B R O U T I N E S ************
- ArchiveOldLocAndTime ; move oldMouseLoc & oldTime into archiveMouse & archiveTime
- LEA oldTime, A1
- LEA archiveTime, A0
- MOVE.L (A1), (A0)
- LEA oldMouseLoc, A1
- LEA archiveMouse, A0
- MOVE.L (A1), (A0)
- RTS
-
- UpdateOldLocAndTime ; get the latest mouseLoc & time
- LEA oldMouseLoc, A1
- MOVE.L A1, -(SP) ; push the VAR mouseLoc
- _GetMouse ; find the current location
- LEA oldTime, A0
- MOVE.L Ticks, (A0) ; update to the current time
- RTS
-
- SetLocAndTime
- MOVE.L Ticks, D0 ; what time is it?
- LEA oldTime, A1
- SUB.L (A1), D0 ; how long has it been since we last checked?
- CMPI.L #lagTime, D0 ; see if enough time has elapsed
- BLT.S tooSoon ; not yet, maybe next time
- JSR ArchiveOldLocAndTime
- JSR UpdateOldLocAndTime
- tooSoon
- RTS
-
- CheckCurrApp
- MOVEQ #0, D0 ; init our result to false
- MOVE.L CurApName, D1 ; get the first 4 bytes of the application
- CMP.L FinderName, D1 ; compare the first 4 bytes (including length byte)
- BNE.S notFinder
- MOVE.W CurApName+4, D1 ; get the next 2 bytes
- CMP.W FinderName+4, D1 ; compare the next 2 bytes
- BNE.S notFinder
- MOVE.B CurApName+6, D1 ; get the last byte
- CMP.B FinderName+6, D1 ; compare the last byte
- BNE.S notFinder
- MOVEQ #1, D0 ; it’s true, the current application is the Finder
- notFinder
- RTS
-
- ScratchParam
- oldDragTrap DC.L $FFFFFFFF ; original DragGrayRgn procedure ptr stored here
- oldActionProc DC.L $FFFFFFFF ; the ActionProc of my DragGrayRgn caller is kept here
- oldMouseLoc DC.L $FFFFFFFF ; a mouse Loc point is stored here
- archiveMouse DC.L $FFFFFFFF ; a mouse Loc point is stored here
- oldTime DC.L $FFFFFFFF ; a value of time ( Ticks ) is stored here
- archiveTime DC.L $FFFFFFFF ; a value of time ( Ticks ) is stored here
- myKeyMap DC.L $00000000 ; a KeyMap is stored here
- DC.L $00000000 ; a KeyMap is a packed array[0..127] of boolean
- DC.L $00000000 ; which equals 16 bytes
- DC.L $00000000
- theWorld DC.L $00000000 ; a rect that is the bounds of the screen
- DC.L $00000000
- ZeroPotential DC.W $0002
-
- TossParam
- DeskFric DC.W $0001 ; the Desk Friction value is stored here
- BounceFric DC.W $0008 ; the Bounce Friction value is stored here
- GravForce DC.W $0010 ; the Gravitational Force is stored here
- ClockDir DC.W $0006
- GravVect DC.L $00400000 ; Gravitational v & h Vectors
- MoIsRunning DC.B $01
- OnlyInFinder DC.B $00
- MakeSound DC.W $FFFF ; should we make a sound when it bounces?
- SndResNum DC.W $8100 ; this is a nice short blip sound in the System
- SndChannel DC.L $00000000
- yVelocity DC.L $10002000 ; region velocity v vector
- xVelocity DC.L $30004000 ; region velocity h vector
- RegionLoc DC.L $00000000 ; region location point
- ElapsedTicks DC.L $00000000 ; time since last moved ( Ticks )
- LongPositionH DC.L $00000000
- LongPositionV DC.L $00000000
- NoMoveCycles DC.W $0000
- LastSoundTime DC.L $00000000
- MedGraySmoke DC.L $92244992
- DC.L $24499224
- LtGraySmoke DC.L $88221144
- DC.L $88221144
- Finish
-
-
- ENDFUNC
-
-
- END
-